#include <sys/queue.h>
#include"pthread.hpp"
#include<queue>
#include<pthread.h>
#include<vector>
#include<unistd.h>
#define NUM 5
//复用自己封装的锁实现
class Task
{
public:
    Task()
    {
        ;
    }
    Task(int x,int y,char op)
    :_x(x)
    ,_y(y)
    ,_op(op)
    {
        ;
    }
    void operator()()
    {
        switch(_op)
        {
            case '+':
            {
                _result = _x + _y;
                _exitcode = 0;
            }
            break;
            case '-':
            {
                _result = _x - _y;
                _exitcode = 0;
            }
            break;
            case '*':
            {
                _result = _x * _y;
                _exitcode = 0;
            }
            break;
            case '/':
            {
                if(_y == 0)
                    _exitcode = 1;
                else 
                _result = _x / _y;
            }
                break;
             case '%':
            {   
                if(_y == 0)
                    _exitcode = 1;
                else    
                _result = _x % _y;
            }
            break;
        }
    }
    std::string getformat()
    {
        return  std::to_string(_x) + _op + std::to_string(_y)+'?';
    }
    std::string getRformat()
    {
        return std::to_string(_result) + "("+ std::to_string(_exitcode) + ")";
    }
    int _x;
    int _y;
    char _op;
    int _result;
    int _exitcode = 0;
};
template<class T>
class threadPool
{
public:
    threadPool(int size = NUM) //vp_存的自定义类型要有默认构造,不然这里初始化会找不到默认构造!
    :vp_(size)
    {
        pthread_mutex_init(&mutex_,nullptr);
        pthread_cond_init(&Consumer,nullptr);
        pthread_cond_init(&Productor,nullptr);
    }
    void init()
    {
        for (int i = 0; i < NUM; i++)
        {
            vp_[i] = (Thread(i,threadRun,this));
        }
    }
    void Lock()
    {
        pthread_mutex_lock(&mutex_);
    }
    void Unlock()
    {
        pthread_mutex_unlock(&mutex_);
    }
    static void* threadRun(void* arg)
    {
        // pthread_detach(pthread_self());
        threadPool<T>* tp = static_cast<threadPool<T>*> (arg);
        //执行任务
        while(true)
        {
            T data;
            tp->pop(data);
            std::cout<<data.getformat()<<std::endl;
            data();
            std::cout<<data.getRformat()<<"id: "<<pthread_self()<<std::endl;
        }
    }
    bool Full()
    {
        return tasks_.size() == NUM;
    }
    bool Empty()
    {
        return tasks_.size() == 0;
    }
    void start()
    {
        // for(int i = 0; i < NUM; i++)//创建多线程
        // {
        //     pthread_create(&vp_[i],nullptr,threadRun,this);
        // }
        std::cout<<vp_.size()<<std::endl;
        for(auto& e : vp_)//复用Thread Run方法创建线程
        {
            e.Run();
        }
    }
    ~threadPool()
    {
        for(auto& e : vp_)//复用Thread join方法回收线程
        {
            e.join();
        }
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&Consumer);
        pthread_cond_destroy(&Productor);
    }
    void push(const T&data)
    {
        Lock();
        while(Full())
        {
            pthread_cond_wait(&Productor,&mutex_);
        }
        tasks_.push(data);
        pthread_cond_signal(&Consumer);
        Unlock();
    }
    void pop(T& data)
    {
        Lock();
         //检查是否有任务
        while(Empty())
        {
            pthread_cond_wait(&Consumer,&mutex_);
        }
        data = tasks_.front();
        tasks_.pop();
        pthread_cond_signal(&Productor);
        Unlock();
    }
    std::queue<T> tasks_; //任务队列
    std::vector<Thread> vp_; //线程池,不能存指针,内部要解引用访问的
    pthread_mutex_t mutex_;
    pthread_cond_t Consumer;
    pthread_cond_t Productor;
};